#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
##--------------------------------------------------------------------------##
##
## Copyright (C) 1998-2003 Markus Oberhumer <markus@oberhumer.com>
## Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2010 Skomoroh <skomoroh@users.sourceforge.net>
## Copyright (C) 2010-2013 Jeremy Austin-Bardo <tjaustinbardo@gmail.com>
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
##-- G68 -- S08 ------------------------------------------------------------##
__all__ = []

from .. import comparecards as cmp_cards
from .. import formlib as layout
from .. import pilelib as stack
from .. import quickplayscore as quickplay
from .. import stackfill as fill
from ..forms import gypsy as GypsyLayout
from ..gamelib import state, game, info as gi
from ..hint import CautiousDefaultHint, DefaultHint
from ..packlib import place, info as cs
from ..pilelib import move as a_move
from ..piles import spider
from ..utillib.misc import kwdefault
from . import canfield

GT, SL = gi.GT, gi.SL
Wrap = stack.StackWrapper


class Jane_Talon(stack.OpenAutoTalon):
    """
    Deal 1 card on _reserve_. Last 2 card flip and deal _waste_.
    """

    def cardFlips(self):
        """
        cardFlips() -> bool

        Check pile flip top card. Overide prevent flipping.

        :return: pile flips top card?
        :rtype: boolean
        """
        return False

    def can_deal_cards(self):
        """
        can_deal_cards() -> bool

        Check by Game.talon_deal() if pile can deal more cards. Default is
        while there are 2 or more cards available.

        :return: deal more cards?
        :rtype: True | False
        """
        return len(self.cards) >= 2

    def deal_cards(self, sound=False):
        """
        deal_cards([sound:bool=False]) -> None

        Deal cards for Game.talon_deal() to other piles. Deal
        _reserve_ until 2 cards left and flip over pile and deal _waste_.

        :keyword boolean sound: sound fx?
        """
        num_cards = 0
        if len(self.cards) > 2:
            game = self.game
            num_cards = self.dealRow(game.s['reserves'], sound=sound)
        if len(self.cards) == 2:
            game._move_do(a_move.AFlipAndMoveMove(self, game.s['wastes'][-1],
                                                  frames=4),
                          reset=True)  # low-level
            num_cards += 1
        return num_cards


class Q_C__Talon(stack.WasteTalon):
    """
    Deal 1 card on _waste_ until has cards.
    """

    def deal_cards(self, **kw):
        """
        deal_cards([sound:bool=False]) -> None

        Deal cards for Game.talon_deal() to other piles. Continue deal
        _waste_ until a card does not finish on _foundation_ or have no cards.

        :keyword boolean sound: sound fx?
        """
        while not self.game.s['wastes'][-1].cards:
            super(Q_C__Talon, self).deal_cards(**kw)
            if not self.cards:
                break


class Q_C__WasteStack(stack.WasteStack):
    """
    Build none. Play top. Finish any top on _foundation_.
    """

    def closeStack(self):
        """
        closeStack() -> None

        Perfom actions after addCard() or insertCard(). Check top card for
        foundation.cardsBuild().
        """
        while self.cards:
            pile = cmp_cards.groupTakes(self.game.s['foundations'], self)
            if pile is not None:
                self.play_move_pile(1, self.game.s['foundation'])
            else:
                break


class EightByEight_RowStack(stack.GapTopBuildMethod, stack.RK_RowStack):
    pass


class SevenDevils_RowStack(stack.NotFromReserveBuildMethod,
                           stack.AC_RowStack):
    """
    Build down in rank by alt color from any but _reserve_. Play seq.
    """
    pass


class GoldMine_RowStack(stack.AC_RowStack):
    """
    Build down in rank by alt color. Play seq. _BOTTOM_IMAGE_ is shade.
    """
    _BOTTOM_IMAGE_ = 'shade'


class EightSages_Row(stack.FromWasteBuildMethod, stack.AC_RowStack):
    """
    Build down in rank by alt color from _waste_. Play seq.
    """
    pass


class Klondike(game.Game):
    """
    Finish cards on _foundation_ without limit turn.

    _row_
      Pile 7 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7] card. Build
      down in rank by alt color. Play seq. Base KING.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=INFINITE)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=2, name='Klondike', game_type=(GT.KLONDIKE | GT.POPULAR
                   | GT.GNOME | GT.KDE | GT.XPAT), decks=1, redeals=cs.INFINITE,
                   skill_level=SL.BALANCED, version='1.00')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _layout_ = layout.KlondikeLayout
    _talon_ = Wrap(stack.WasteTalon, max_rounds=cs.INFINITE)
    _waste_ = stack.WasteStack
    _foundation_ = stack.SS_Foundation
    _row_ = Wrap(stack.AC_RowStack, base_rank=cs.KING)
    _hint_ = DefaultHint

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=7, texts=True, playcards=16) -> Layout
        """
        kwdefault(kw, rows=7, texts=True, playcards=16)
        return super(Klondike, self)._create_game(**kw)

    def _start(self, flip=False, reverse=True, **kw):
        """
        Deal initial cards for new game.
          - s[rows]:  [1..len] *flip* *reverse*.

        .. \_start([flip=False, reverse=True]) -> None
        """
        for i in range(1, len(self.s['rows'])):
            self.s['talon'].dealRow(rows=self.s['rows'][i:], frames=0,
                                    flip=flip, reverse=reverse)
        self.s['talon'].dealRow(reverse=reverse)


class VegasKlondike(Klondike):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 7 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7] card. Build
      down in rank by alt color. Play seq. Base KING.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.

    note::
      monetary score shown on canvas
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=129, name='Vegas Klondike', game_type=(GT.KLONDIKE |
                    GT.SCORE), decks=1, skill_level=SL.BALANCED,
                    version='3.20')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = stack.WasteTalon

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.
        Add score texts.

        .. \_create_game(rows=7, texts=True, playcards=16) -> Layout
        """
        l = super(VegasKlondike)._create_game(**kw)
        self.game.texts['score'] = l.create_score_text(None, anchor='sw',
                                                 dx=l.XM, dy=self.height - l.YM)
        return l

    @property
    def score(self):
        """
        casino type scoring
        """
        return sum(5 * len(s.cards) for s in self.s['foundations']
                    ) - self['ncards']

    @state.not_state('is_preview')
    def _update_text(self):
        from ..settings import CONF_OPT
        from ..statdb import STAT_DB
        if not self.texts['score']:
            return
        b1 = STAT_DB.results(CONF_OPT['player'], self['id'], 'score',
                                   'sum', all_=False)
        b2 = self.score
        self.texts['score'].config(text=_('Balance ${0}').format(b1 + b2))


class CasinoKlondike(VegasKlondike):
    """
    Finish cards on _foundation_ within 3 turn.

    _row_
      Pile 7 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7] card. Build
      down in rank by alt color. Play seq. Base KING.

    _talon_
      Pile 1 NW. Deal 3 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.

    note::
      monetary score shown on canvas
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=3, num_deal=3)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=61, name='Casino Klondike', game_type=(GT.KLONDIKE |
                    GT.SCORE), decks=1, redeals=2, skill_level=SL.BALANCED,
                    version='3.00')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, max_rounds=3, num_deal=3)


class KlondikeByThrees(Klondike):
    """
    Finish cards on _foundation_ without limit turn.

    _row_
      Pile 7 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7] card. Build
      down in rank by alt color. Play seq. Base KING.

    _talon_
      Pile 1 NW. Deal 3 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=INFINITE,
      num_deal=3)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=18, name='Klondike by Threes', game_type=(GT.KLONDIKE |
                    GT.KDE), decks=1, redeals=cs.INFINITE,
                    skill_level=SL.MOSTLY_LUCK, version='2.90',
                    altnames=('Klondike (3 Card Deal)',))
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, max_rounds=cs.INFINITE, num_deal=3)


class ThumbAndPouch(Klondike):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 7 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7] card. Build
      down in rank by alt suit. Play seq.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.BO_RowStack
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=58, name='Thumb and Pouch', game_type=(GT.KLONDIKE |
                    GT.GNOME), decks=1, skill_level=SL.MOSTLY_LUCK,
                    version='3.00')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = stack.WasteTalon
    _row_ = stack.BO_RowStack


class Chinaman(ThumbAndPouch):
    """
    Finish cards on _foundation_ within 2 turn.

    _row_
      Pile 7 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7] card. Build
      down in rank by alt suit. Play seq. Base KING.

    _talon_
      Pile 1 NW. Deal 3 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=2, num_deal=3)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.BO_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=634, name='Chinaman', game_type=GT.KLONDIKE, decks=1,
                    redeals=1, skill_level=SL.BALANCED, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, max_rounds=2, num_deal=3)
    _row_ = Wrap(stack.BO_RowStack, base_rank=cs.KING)


class Whitehead(Klondike):
    """
    Finish cards on _foundation_ without limit turn.

    _row_
      Pile 7 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7] card. Build
      down in rank by same color. Play seq by same suit.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: SS_SC_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=67, name='Whitehead', game_type=(GT.KLONDIKE |
                    GT.GNOME), decks=1, skill_level=SL.MOSTLY_SKILL,
                    version='3.00')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = stack.WasteTalon
    _row_ = spider.SS_SC_RowStack
    _hint_ = CautiousDefaultHint

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]:  [1..len] *flip* *reverse*.

        .. \_start([flip=True, reverse=True]) -> None
        """
        kw.setdefault('flip', True)
        super(Whitehead, self)._start(**kw)

    _quickplay_ = quickplay.Spider


class SmallHarp(Klondike):
    """
    Finish cards on _foundation_ without limit turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.gypsy.GypsyLayout
        - row [7 horz NW, vert offset]
        - talon [1 SE, no offset]
        - waste [1 W, no offset]
        - foundation [4 vert E, no offset]

    _row_
      Pile 7 horz W _foundation_. Init deal [7, 6, 5, 4, 3, 2, 1] card. Build
      down in rank by alt color. Play seq. Base KING.

    _talon_
      Pile 1 SE. Deal 1 card on _waste_.

    _waste_
      Pile 1 W _talon_. Build none. Play top.

    _foundation_
      Pile 4 vert E. Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=INFINITE)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=39, name='Small Harp', game_type=(GT.KLONDIKE |
                    GT.ATARI), decks=1, redeals=cs.INFINITE, version='3.00',
                    skill_level=SL.BALANCED, altnames=('Die kleine Harfe',))
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _layout_ = GypsyLayout.GypsyLayout

    def _start(self, flip=False, **kw):
        """
        Deal initial cards for new game.
          - s[rows]:  [len..1] *flip* all open.

        .. \_start([flip=False]) -> None
        """
        for i in range(len(self.s['rows'])):
            self.s['talon'].dealRow(rows=self.s['rows'][:i], flip=flip,
                                    frames=0)
        self.s['talon'].dealRow()


class Eastcliff(Klondike):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 7 horz S _foundation_. Init deal 3 card. Build down in rank by alt
      color. Play seq.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=66, name='Eastcliff', game_type=GT.KLONDIKE, decks=1,
                    skill_level=SL.BALANCED, version='3.00')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = stack.WasteTalon
    _row_ = stack.AC_RowStack

    def _start(self, rows=3, flip=False, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: *rows* ea *flip* all open.

        .. \_start([flip=False, rows=3]) -> None
        """
        for i in range(rows - 1):
            self.s['talon'].dealRow(flip=flip, frames=0)
        self.s['talon'].dealRow()


class Easthaven(Eastcliff):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 7 horz S _foundation_. Init deal 3 card. Build down in rank by alt
      color. Play seq.

    _talon_
      Pile 1 NW. Deal 1 card on _row_.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=224, name='Easthaven', game_type=(GT.GYPSY | GT.GNOME),
                    decks=1, skill_level=SL.MOSTLY_LUCK, version='4.60')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = stack.DealRowTalon
    _waste_ = None


class DoubleEasthaven(Easthaven):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 8 horz S _foundation_. Init deal 3 card. Build down in rank by alt
      color. Play seq.

    _talon_
      Pile 1 NW. Deal 1 card on _row_.

    _foundation_
      Pile 8 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=452, name='Double Easthaven', game_type=GT.GYPSY,
                    decks=2, skill_level=SL.MOSTLY_SKILL,
                    version='0.92fc', altnames=('Easthaven (2 Decks)',))
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=8, playcards=20) -> Layout
        """
        kwdefault(kw, rows=8, playcards=20)
        return super(DoubleEasthaven, self)._create_game(**kw)


class TripleEasthaven(Easthaven):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 12 horz S _foundation_. Init deal 3 card. Build down in rank by alt
      color. Play seq.

    _talon_
      Pile 1 NW. Deal 1 card on _row_.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=453, name='Triple Easthaven', game_type=GT.GYPSY,
                    decks=3, skill_level=SL.MOSTLY_SKILL,
                    version='0.92fc', altnames=('Easthaven (3 Decks)',))
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=12, playcards=26) -> Layout
        """
        kwdefault(kw, rows=12, playcards=26)
        return super(TripleEasthaven, self)._create_game(**kw)


class Westcliff(Eastcliff):
    """
    Finish cards on _foundation_ within 2 turn.

    _row_
      Pile 10 horz S _foundation_. Init deal 3 card. Build down in rank by alt
      color. Play seq.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation (max_move=0)
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=33, name='Westcliff', game_type=(GT.KLONDIKE |
                    GT.CHILDREN | GT.GNOME), decks=1, version='2.90',
                    skill_level=SL.MOSTLY_LUCK)
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _foundation_ = Wrap(stack.SS_Foundation, max_move=0)

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=10) -> Layout
        """
        kw.setdefault('rows', 10)
        return super(Westcliff, self)._create_game(**kw)


class Westhaven(Easthaven):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 10 horz S _foundation_. Init deal 3 card. Build down in rank by alt
      color. Play seq.

    _talon_
      Pile 1 NW. Deal 1 card on _row_.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation (max_move=0)
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=225, name='Westhaven', game_type=(GT.GYPSY | GT.GNOME),
                    decks=1, skill_level=SL.BALANCED, version='4.60')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _foundation_ = Wrap(stack.SS_Foundation, max_move=0)

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=10) -> Layout
        """
        kw.setdefault('rows', 10)
        return super(Westhaven, self)._create_game(**kw)


class PasSeul(Eastcliff):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 6 horz S _foundation_. Init deal 1 card. Build down in rank by alt
      color. Play seq.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=107, name='Pas Seul', game_type=GT.KLONDIKE, decks=1,
                    skill_level=SL.BALANCED, version='3.00')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=6) -> Layout
        """
        kw.setdefault('rows', 6)
        return super(PasSeul, self)._create_game(**kw)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]:  *row* ea *flip* all open.

        .. \_start([flip=False, rows=1]) -> None
        """
        kw.setdefault('rows', 1)
        super(PasSeul, self)._start(**kw)


class BlindAlleys(Eastcliff):
    """
    Finish cards on _foundation_ within 2 turn.

    _row_
      Pile 6 horz S _foundation_. Init deal 3 card. Build down in rank by alt
      color. Play seq.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Init deal base ACE. Build up in rank by same suit. Play
      top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=2)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=81, name='Blind Alleys', game_type=GT.KLONDIKE,
                    decks=1, redeals=1, skill_level=SL.MOSTLY_LUCK,
                    version='3.00')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, max_rounds=2)

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=6) -> Layout
        """
        kw.setdefault(rows=6)
        return super(BlindAlleys, self)._create_game(**kw)

    def _pack_place(self, cards):
        """
        _pack_place(cards:seq(Card ...)) -> seq(Card ...)

        Overide to return ACE on top by rank, suit, deck for _foundation_ deal.
        """
        return place.MoveToTop(cards, place.AllAces)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[foundations]: 1 ea open.
          - s[rows]: *rows* ea *flip* all open.

        .. \_start([flip=False, rows=3]) -> None
        """
        self.s['talon'].dealRow(rows=self.s['foundations'], frames=0)
        super(BlindAlleys, self)._start(**kw)


class Somerset(Klondike):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 10 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7, 8, 8, 8]
      open card. Build down in rank by alt color. Play seq as top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SuperMoveAC_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=215, name='Somerset', game_type=(GT.BELEAGUERED_CASTLE
                    | GT.OPEN), decks=1, version='4.60',
                    skill_level=SL.MOSTLY_SKILL)
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = stack.InitialDealTalon
    _waste_ = None
    _row_ = stack.SuperMoveAC_RowStack
    _hint_ = CautiousDefaultHint

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=10, texts=False) -> Layout
        """
        kwdefault(kw, rows=10, texts=False)
        return super(Somerset, self)._create_game(**kw)

    def _start(self, rows=8, **kw):
        """
        Deal initial cards for new game.
          - s[rows]:  [1..8, 8, 8] open.

        .. \_start([rows=8]) -> None
        """
        frames = 0
        for i in range(rows):
            self.s['talon'].dealRow(rows=self.s['rows'][i:], frames=frames)
            if i == rows - 3:
                frames = -1


class Morehead(Somerset):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 10 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7, 8, 8, 8]
      open card. Build down in rank by alt suit. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SuperMoveAC_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=362, name='Morehead', game_type=(GT.BELEAGUERED_CASTLE
                    | GT.OPEN), decks=1, version='0.90fc',
                    skill_level=SL.MOSTLY_SKILL)
    __author__ = 'Skomoroh'
    __credits__ = ['Albert Morehead', 'Geoffrey Mott-Smith']
    __version__ = 7.70

    _row_ = Wrap(stack.BO_RowStack, max_move=1)


class Usk(Somerset):
    """
    Finish cards on _foundation_ within 2 turn.

    _row_
      Pile 10 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7, 8, 8, 8]
      open card. Build down in rank by alt suit. Play top.

    _talon_
      Pile 1 NW. Reset and redeal [1, 2, 3,..] _row_.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.RedealTalon (max_rounds=2)
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=539, name='Usk', game_type=GT.KLONDIKE, decks=1,
                    redeals=1, skill_level=SL.BALANCED, version='0.9.3fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = Wrap(stack.RedealTalon, max_rounds=2)
    _row_ = Wrap(stack.AC_RowStack, base_rank=cs.KING)

    def talon_redeal(self, sound=True):
        """
        talon_redeal(self, sound=True):

        Redeal from talon after 1st round after cards returned to refill _row_
        with increasing cards each pile until empty. Returns num cards dealt.
        """
        n = 0
        while self.s['talon'].cards:
            self.s['talon'].dealRowAvail(rows=self.s['rows'][n:], frames=4)
            n += 1


class AmericanCanister(Klondike):
    """
    Finish cards on _foundation_ within 1 turn.

    _layout_
     .. layout.KlondikeLayout
    _row_
      .. stack.AC_RowStack
      Pile 8 horz S _foundation_. Init deal [6, 6, 4, 4, 4, 4, 6, 6] card.
      Build down in rank by alt color. Play seq.
    _foundation_
      .. stack.SS_Foundation
      Pile 4 horz N.
      Build up in rank by same suit. Play top.
    _talon_
      .. stack.InitialDealTalon
    _hint_
      .. hint.DefaultHint
    """
    __info__ = dict(id=601, name='American Canister',
                    game_type=(GT.BELEAGUERED_CASTLE | GT.OPEN), decks=1,
                    skill_level=SL.MOSTLY_SKILL, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = stack.InitialDealTalon
    _waste_ = None
    _row_ = stack.AC_RowStack

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=8, texts=False) -> Layout
        """
        kwdefault(kw, rows=8, texts=False)
        return super(AmericanCanister, self)._create_game(**kw)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: [6, 6, 4, 4, 4, 4, 6, 6] open.

        .. \_start([]) -> None
        """
        for i in range(5):
            self.s['talon'].dealRow(frames=0)
        self.s['talon'].dealRow()
        self.s['talon'].dealRow(rows=self.s['rows'][2:6])


class Canister(AmericanCanister):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 8 horz S _foundation_. Init deal [6, 6, 4, 4, 4, 4, 6, 6] card.
      Build down in rank alone. Play seq.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.RK_RowStack
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=231, name='Canister', game_type=(GT.BELEAGUERED_CASTLE
                    | GT.OPEN), decks=1, version='4.60',
                    skill_level=SL.MOSTLY_SKILL)
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _row_ = stack.RK_RowStack


class BritishCanister(AmericanCanister):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 8 horz S _foundation_. Init deal [6, 6, 4, 4, 4, 4, 6, 6] card.
      Build down in rank by alt color. Play top. Base KING.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (base_rank=KING, max_move=1)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=602, name='British Canister',
                    game_type=(GT.BELEAGUERED_CASTLE | GT.OPEN), decks=1,
                    skill_level=SL.MOSTLY_SKILL, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = Wrap(stack.AC_RowStack, base_rank=cs.KING, max_move=1)


class AgnesSorel(Klondike):
    """
    Finish cards on _foundation_ within 1 turn.

    _layout_
      .. layout.KlondikeLayout
    _row_
      .. stack.SC_RowStack (mod=13, base_rank=GAP)
      Pile 7 horz S _foundation_. Init deal [1..7] open card.
      Build down in rank by same color. Play seq. Base none.
    _talon_
      .. stack.DealRowTalon
      Pile 1 NW.
      Deal 1 card on _row_.
    _foundation_
      .. stack.Vary_SS_Foundation (max_move=0)
      Pile 4 horz N. Init deal 1 base card.
      Build up in rank by same suit from base wrap. Play none.
    _hint_
      .. hint.DefaultHint
    """
    __info__ = dict(id=229, name='Agnes Sorel', game_type=(GT.GYPSY |
                    GT.GNOME), decks=1, skill_level=SL.MOSTLY_LUCK,
                    version='4.60')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = stack.DealRowTalon
    _waste_ = None
    _foundation_ = Wrap(stack.Vary_SS_Foundation, max_move=0)
    _row_ = Wrap(stack.SC_RowStack, mod=13, base_rank=cs.GAP)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]:  [1..7] top open.
          - s[foundations]: BASE. Set base rank.

        .. \_start([flip=False, reverse=True]) -> None
        """
        kw.setdefault('flip', True)
        super(AgnesSorel, self)._start(flip=flip, **kw)
        base_rank = self.s['talon'].TOPCARD['rank']
        self.s['talon'].dealBaseCard(ncards=1, saveinfo=False)
        self._save_stack_caps(self.s['foundations'], base_rank=base_rank)


class EightTimesEight(Klondike):
    """
    Finish cards on _foundation_ without limit turn.

    :CVariables:
      _layout_ : pysollib.layout.Layout
        .. pysollib.layouts.gypsy.GypsyLayout
        - row [8 horz NW, vert offset]
        - talon [1 SE, no offset]
        - waste [1 W, no offset]
        - foundation [4 vert E, no offset]

    _row_
      Init deal 8 card. Build down in rank by alt
      color. Play seq.

    _talon_
      Deal 1 card on _waste_.

    _waste_
      Build none. Play top.

    _foundation_
      Build up in rank by same suit. Play top.
    ------
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=INFINITE)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=4, name='8 × 8', game_type=(GT.KLONDIKE | GT.ATARI),
                    decks=2, redeals=cs.INFINITE, skill_level=SL.BALANCED,
                    version='1.00')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _layout_ = GypsyLayout.GypsyLayout
    _row_ = stack.AC_RowStack

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=8) -> Layout
        """
        kw.setdefault('rows', 8)
        super(EightTimesEight, self)._create_game(**kw)

    def _start(self, rows=8, flip=True, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: 8 ea open.

        .. \_start([rows=8, flip=True]) -> None
        """
        for i in range(rows - 1):
            self.s['talon'].dealRow(flip=flip, frames=0)
        self.s['talon'].dealRow()


class AchtmalAcht(EightTimesEight):
    """
    Finish cards on _foundation_ within 3 turn.

    :CVariables:
      _layout_: {Layout}
        .. gypsy.GypsyLayout
        - row [8 horz NW, vert offset]
        - talon [1 SE, no offset]
        - waste [1 W, no offset]
        - foundation [4 vert E, no offset]

    _row_: {Pile}
      .. stack.AC_RowStack
      Build down in rank by alt color. Play seq.

    _talon_: {Pile}
      .. stack.WasteTalon(max_rounds=3)
      Deal 1 card on _waste_.

    _waste_: {Pile}
      .. stack.WasteStack
      Build none. Play top.

    _foundation_: {Pile}
      .. stack.SS_Foundation
      Build up in rank by same suit. Play top.

    _hint_: {Hint}
      .. hint.DefaultHint
    """
    __info__ = dict(id=127, name='Eight Times Eight', game_type=GT.KLONDIKE,
                    decks=2, redeals=2, skill_level=SL.BALANCED,
                    altnames=('Achtmal Acht',), version='3.10')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, max_rounds=3)


class EightByEight(EightTimesEight):
    """
    Finish cards on _foundation_ within 3 turn.

    _row_
      Pile 8 horz S _foundation_. Init deal 8 card. Build down in rank alone.
      Play seq on cards, top on gap.

    _talon_
      Pile 1 NW. Deal 3 card on _waste_. Each turn deal -1 card.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: canfield.CanfieldRush_Talon (max_rounds=3)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: EightByEight_RowStack
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=651, name='Eight by Eight', game_type=GT.KLONDIKE,
                    decks=2, redeals=2, skill_level=SL.BALANCED,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _layout_ = layout.KlondikeLayout
    _talon_ = Wrap(canfield.CanfieldRush_Talon, max_rounds=3)
    _row_ = EightByEight_RowStack

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(playcards=20) -> Layout
        """
        kw.setdefault('playcards', 20)
        return super(EightByEight, self)._create_game(**kw)


class Batsford(Klondike):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 10 horz S _foundation_. Init deal [1..10] card.
      Build down in rank by alt color. Play seq. Base KING.

    _reserve_
      Pile 1 SW. Build 3 by same rank. Play top. Base KING.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (base_rank=KING)
    :cvar Stack _reserve_: stack.ReserveStack (max_cards=3, rank=KING)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=133, name='Batsford', game_type=GT.KLONDIKE, decks=2,
                    skill_level=SL.BALANCED, version='3.20')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = stack.WasteTalon
    _reserve_ = Wrap(stack.ReserveStack, max_cards=3, rank=cs.KING)

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.
        Override add custom reserve sw corner with ncard text.

        .. \_create_game(rows=10, playcards=22, round_text='ne') -> Layout
        """
        kwdefault(kw, rows=10, playcards=22, round_text='ne')
        l, s = super(Batsford, self)._create_game(**kw), self.s
        x, y = l.XM, self.height - l.YS
        s['reserves'] = [self._reserve_(x, y, game=self)]
        self._set_region(s['reserves'], l._region(y=y - l.YM - l.HCH,
                                              w=x + l.XS - l.HCW), priority=1)
        l.set_ncards_text(s['reserves'][0], 'se')
        l.defaultStackGroups()
        return l


class BatsfordAgain(Batsford):
    """
    Finish cards on _foundation_ within 2 turn.

    _row_
      Pile 10 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      card. Build down in rank by alt color. Play seq. Base KING.

    _reserve_
      Pile 1 SW. Build 3 by same rank. Play top. Base KING.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=2)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (base_rank=KING)
    :cvar Stack _reserve_: stack.ReserveStack (max_cards=3, rank=KING)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=541, name='Batsford Again', game_type=GT.KLONDIKE,
                    decks=2, redeals=1, skill_level=SL.BALANCED,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, max_rounds=2)


class Jumbo(Klondike):
    """
    Finish cards on _foundation_ within 2 turn.

    _row_
      Pile 9 horz S _foundation_. Init deal [9, 8, 7, 6, 5, 4, 3, 2, 1] card.
      Build down in rank by alt color. Play seq. Base KING.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=2)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=283, name='Jumbo', game_type=(GT.KLONDIKE | GT.GNOME),
                    decks=2, redeals=1, skill_level=SL.BALANCED,
                    version='0.80fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, max_rounds=2)

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=9) -> Layout
        """
        kw.setdefault('rows', 9)
        return super(Jumbo, self)._create_game(**kw)

    def _start(self, flip=False, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: [9..1] top open.

        .. \_start([flip=False]) -> None
        """
        for i in range(len(self.s['rows'])):
            self.s['talon'].dealRow(rows=self.s['rows'][:i], flip=flip,
                                    frames=0)
        self.s['talon'].dealRow()


class OpenJumbo(Jumbo):
    """
    Finish cards on _foundation_ within 2 turn.

    _row_
      Pile 9 horz S _foundation_. Init deal [9, 8, 7, 6, 5, 4, 3, 2, 1] open
      card. Build down in rank by alt color. Play seq. Base KING.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=2)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=333, name='Open Jumbo', game_type=GT.KLONDIKE,
                    decks=2, redeals=1, skill_level=SL.BALANCED,
                    version='0.90fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: [9..1] open.

        .. \_start([rows=10, flip=True]) -> None
        """
        kw.setdefault('flip', True)
        super(OpenJumbo, self)._start(**kw)


class KingAlbert(Klondike):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 9 horz S _foundation_. Init deal [1..9] card.
      Build down in rank by alt color. Play top.

    _reserve_
      Pile 7 over 2 col E. Init deal 1 card. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.DukeLayout
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (max_move=1)
    :cvar Stack _reserve_: stack.OpenStack
    :cvar Hint _hint_ = CautiousDefaultHint
    """
    __info__ = dict(id=233, name='King Albert', game_type=(GT.RAGLAN |
                    GT.OPEN | GT.GNOME), decks=1, skill_level=SL.MOSTLY_SKILL,
                    altnames=('Idiotʼs Delight',), version='4.60')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _layout_ = layout.DukeLayout
    _talon_ = stack.InitialDealTalon
    _waste_ = None
    _row_ = Wrap(stack.AC_RowStack, max_move=1)
    _reserve_ = stack.OpenStack
    _hint_ = CautiousDefaultHint

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=9, reserves=7, ncols=2, texts=False) -> Layout
        """
        kwdefault(kw, rows=9, reserves=7, ncols=2, texts=False)
        return super(KingAlbert, self)._create_game(**kw)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]:  [1..9] open.
          - s[reserves]: 1 ea open

        .. \_start([flip=True, reverse=False]) -> None
        """
        kwdefault(kw, flip=True, reverse=False)
        super(KingAlbert, self)._start(**kw)
        self.s['talon'].dealRow(rows=self.s['reserves'])


class Stonewall(KingAlbert):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 6 horz S _foundation_. Init deal 6 alt open card. Build down in
      rank by alt color. Play seq.

    _reserve_
      Pile 16 over 4 col E. Init deal 1 card. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.

    seealso::
      <http://en.wikipedia.org/wiki/Stonewall_%28solitaire%29>
    ------
    :cvar Layout _layout_: layout.DukeLayout
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Stack _reserve_: stack.OpenStack
    :cvar Hint _hint_ = CautiousDefaultHint
    """
    __info__ = dict(id=221, name='Stonewall', game_type=GT.RAGLAN, decks=1,
                    skill_level=SL.MOSTLY_LUCK, version='4.60')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _row_ = stack.AC_RowStack

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=6, reserves=16, ncols=4, texts=False) -> Layout
        """
        kwdefault(kw, rows=6, reserves=16, ncols=4, texts=False)
        return super(Stonewall, self)._create_game(**kw)

    def _start(self, flips=(False, True,) * 3, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: 6 ea alt open.
          - s[reserves]: 1 ea open

        .. \_start([flips=(False, True,) * 3]) -> None
        """
        for flip in flips[:-1]:
            self.s['talon'].dealRow(flip=flip, frames=0)
        self.s['talon'].dealRow(flip=flips[-1])
        self.s['talon'].dealRow(rows=self.s['reserves'])


class FlowerGarden(Stonewall):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 6 horz S _foundation_. Init deal 6 open card. Build down in rank
      alone. Play seq.

    _reserve_
      Pile 16 over 4 col E. Init deal 1 card. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.

    seealso::
      <http://en.wikipedia.org/wiki/Flower_Garden_%28solitaire%29>
    ------
    :cvar Layout _layout_: layout.DukeLayout
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.RK_RowStack (max_move=1)
    :cvar Stack _reserve_: stack.OpenStack
    :cvar Hint _hint_ = CautiousDefaultHint
    """
    __info__ = dict(id=222, name='Flower Garden', game_type=(GT.RAGLAN |
                    GT.OPEN), decks=1, skill_level=SL.MOSTLY_SKILL,
                    altnames=('The Bouquet', 'The Garden',), version='4.60')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _row_ = Wrap(stack.RK_RowStack, max_move=1)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: 6 ea open.
          - s[reserves]: 1 ea open

        .. \_start([flips=(True,) * 6]) -> None
        """
        kw.setdefault('flips', (True,) * 6)
        return super(FlowerGarden, self)._start(**kw)


class Raglan(KingAlbert):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 7 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7] open card.
      Build down in rank by alt color. Play top.

    _reserve_
      Pile 6 over 2 col E. Init deal 1 card. Build none. Play top.

    _foundation_
      Pile 4 horz N. Init deal base ACE. Build up in rank by same suit. Play
      top.
    ------
    :cvar Layout _layout_: layout.DukeLayout
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.RK_RowStack (max_move=1)
    :cvar Stack _reserve_: stack.OpenStack
    :cvar Hint _hint_ = CautiousDefaultHint
    """
    __info__ = dict(id=232, name='Raglan', game_type=(GT.RAGLAN | GT.OPEN),
                    decks=1, skill_level=SL.MOSTLY_SKILL,
                    version='4.60')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(reserves=6, ncols=2) -> Layout
        """
        kwdefault(kw, reserves=6, ncols=2)
        return super(Raglan, self)._create_game(**kw)

    def _pack_place(self, cards):
        """
        _pack_place(cards:seq(Card ...)) -> seq(Card ...)

        Overide to return ACE on bottom by rank, suit, deck for _foundation_
        deal.
        """
        return place.MoveToBottom(cards, place.AllAces)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]:  [1, 2, 3, 4, 5, 6, 7] open.
          - s[reserves]: 1 ea open
          - s[foundations]: all ACE.

        .. \_start([flip=True, reverse=False]) -> None
        """
        super(Raglan, self)._start(**kw)
        self.s['talon'].dealRow(rows=self.s['foundations'])


class Brigade(Raglan):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 7 horz S _foundation_. Init deal 5 open card. Build down in rank
      alone. Play top.

    _reserve_
      Pile 13 over 4 col E. Init deal 1 card. Build none. Play top.

    _foundation_
      Pile 4 horz N. Init deal base ACE. Build up in rank by same suit. Play
      top.
    ------
    :cvar Layout _layout_: layout.DukeLayout
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.RK_RowStack (max_move=1)
    :cvar Stack _reserve_: stack.OpenStack
    :cvar Hint _hint_ = CautiousDefaultHint
    """
    __info__ = dict(id=223, name='Brigade', game_type=(GT.RAGLAN | GT.OPEN),
                    decks=1, skill_level=SL.MOSTLY_SKILL,
                    version='4.60')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _row_ = Wrap(stack.RK_RowStack, max_move=1)

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=7, reserves=13, ncols=4) -> Layout
        """
        kwdefault(kw, rows=7, reserves=13, ncols=4)
        return super(Brigade, self)._create_game(**kw)

    def _start(self, rows=5, flip=True, **kw):
        """
        Deal initial cards for new game.
          - s[rows]:  5 ea open.
          - s[reserves]: 1 ea open
          - s[foundations]: all ACE.

        .. \_start([flip=True, rows=5]) -> None
        """
        for i in range(rows - 1):
            self.s['talon'].dealRow(flip=flip, frames=0)
        self.s['talon'].dealRow()
        self.s['talon'].dealRow(rows=self.s['reserves'])
        self.s['talon'].dealRow(rows=self.s['foundations'])


class QueenVictoria(KingAlbert):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 9 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7, 8, 9] card.
      Build down in rank by alt color. Play seq.

    _reserve_
      Pile 7 over 2 col E. Init deal 1 card. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.DukeLayout
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Stack _reserve_: stack.OpenStack
    :cvar Hint _hint_ = CautiousDefaultHint
    """
    __info__ = dict(id=627, name='Queen Victoria', game_type=(GT.RAGLAN |
                    GT.OPEN), decks=1, skill_level=SL.MOSTLY_SKILL,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = stack.AC_RowStack


class NorthwestTerritory(KingAlbert):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 8 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7, 8] card.
      Build down in rank by alt color. Play seq. Base KING.

    _reserve_
      Pile 16 over 4 col E. Init deal 1 card. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.DukeLayout
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (base_rank=KING)
    :cvar Stack _reserve_: stack.OpenStack
    :cvar Hint _hint_ = CautiousDefaultHint
    """
    __info__ = dict(id=361, name='Northwest Territory', game_type=GT.RAGLAN,
                    decks=1, skill_level=SL.BALANCED,
                    version='0.90fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = Wrap(stack.AC_RowStack, base_rank=cs.KING)

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=8, reserves=16, ncols=4) -> Layout
        """
        kwdefault(kw, rows=8, reserves=16, ncols=4)
        return super(NorthwestTerritory, self)._create_game(**kw)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]:  [1, 2, 3, 4, 5, 6, 7] top open.
          - s[reserves]: 1 ea open.

        .. \_start([flip=False, reverse=False]) -> None
        """
        kwdefault(kw, flip=False, reverse=False)
        super(NorthwestTerritory, self)._start(**kw)


class ArticGarden(NorthwestTerritory):
    """
    Finish cards on _foundation_ within 1 turn.

    _layout_
      .. layout.DukeLayout
    _row_
      .. stack.AC_RowStack (base_rank=KING)
      Pile 8 horz S _foundation_. Init deal [1..8] open card.
      Build down in rank by alt color. Play seq. Base KING.
    _reserve_
      .. stack.OpenStack
      Pile 16 over 4 col E. Init deal 1 card.
      Build none. Play top.
    _foundation_
      .. stack.SS_Foundation
      Pile 4 horz N.
      Build up in rank by same suit. Play top.
    _talon_
      .. stack.InitialDealTalon
    _hint_
      .. CautiousDefaultHint
    """
    __info__ = dict(id=522, name='Artic Garden', game_type=GT.RAGLAN, decks=1,
                    skill_level=SL.MOSTLY_SKILL, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]:  [1..8] open.
          - s[reserves]: 1 ea open.

        .. \_start([flip=True, reverse=False]) -> None
        """
        kw.setdefault('flip', True)
        super(ArticGarden, self)._start(**kw)


class Jane(Klondike):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 7 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7] card.
      Build down in rank by alt color. Play top. Base rank less then
      _foundation_.

    _reserve_
      Pile 7 over 2 col E. Init deal 1 card. Build none. Play top.

    _talon_
      Pile 1 NW. Deal 1 card on _reserve_. Last 2 card flip and deal _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Init deal base card. Build up in rank by same suit from
      base wrap. Play top.
    ------
    :cvar Layout _layout_: layout.JaneLayout
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.Vary_SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (max_move=1)
    :cvar Stack _reserve_: stack.OpenStack
    :cvar Hint _hint_ = CautiousDefaultHint
    """
    __info__ = dict(id=230, name='Jane', game_type=(GT.RAGLAN | GT.GNOME),
                    decks=1, skill_level=SL.BALANCED, version='4.60')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _layout_ = layout.JaneLayout
    _talon_ = Wrap(Jane_Talon, max_rounds=1)
    _foundation_ = stack.Vary_SS_Foundation
    _row_ = Wrap(stack.AC_RowStack, mod=13)
    _reserves_ = stack.OpenStack

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.
        Add talon to dropstacks.

        .. \_create_game(rows=7, reserves=7, playcards=16, texts=False)
             -> Layout
        """
        kwdefault(kw, rows=7, reserves=7, playcards=16, texts=False)
        l, s = super(Jane, self)._create_game(**kw), self.s
        self.sg['dropstacks'] += [s['talon']]
        return l

    def _start(self,e, **kw):
        """
        Deal initial cards for new game.
          - s[rows]:  [1, 2, 3, 4, 5, 6, 7] top open. Set base rank.
          - s[reserves]: 1 ea open.
          - s[foundations]: BASE. Set base rank.

        .. \_start([flip=False, reverse=True]) -> None
        """
        kwdefault(kw, flip=False)
        super(Jane, self)._start(**kw)
        self.s['talon'].dealRow(rows=self.s['reserves'])
        base_rank = self.s['talon'].TOPCARD['rank']
        self.s['talon'].dealBaseCards(ncards=1, saveinfo=False)
        self._save_stack_caps(self.s['foundations'], base_rank=base_rank)
        self._save_stack_caps(self.s['rows'], base_rank=(base_rank - 1) % 13)

    def _auto_deal(self, sound=True):
        return False


class AgnesBernauer(Jane):
    """
    Finish cards on _foundation_ within 1 turn.

    _layout_
      .. layout.JaneLayout
    _row_
      .. stack.AC_RowStack (max_move=1)
      Pile 7 horz S _foundation_. Init deal [1..7] open card.
      Build down in rank by alt color. Play top. Base rank less then
      _foundation_.
    _reserve_
      .. stack.OpenStack
      Pile 7 over 2 col E. Init deal 1 card.
      Build none. Play top.
    _talon_
      .. stack.DealReserveTalon
      Pile 1 NW.
      Deal 1 card on _reserve_.
    _waste_
      .. stack.WasteStack
      Pile 1 E _talon_.
      Build none. Play top.
    _foundation_
      .. stack.Vary_SS_Foundation (max_move=0)
      Pile 4 horz N. Init deal base card.
      Build up in rank by same suit from base wrap. Play none.
    _hint_
      .. hint.CautiousDefaultHint
    """
    __info__ = dict(id=236, name='Agnes Bernauer', game_type=GT.RAGLAN,
                    decks=1, skill_level=SL.BALANCED,
                    version='4.60')
    __author__ = 'Markus Oberhumer'
    __version__ = 7.70

    _talon_ = stack.DealReserveTalon
    _foundation_ = Wrap(stack.Vary_SS_Foundation, max_move=0)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]:  [1, 2, 3, 4, 5, 6, 7] open. Set base rank.
          - s[reserves]: 1 ea open.
          - s[foundations]: BASE. Set base rank.

        .. \_start([flip=True, reverse=True]) -> None
        """
        kw.setdefault('flip', True)
        super(AgnesBernauer, self)._start(**kw)


class SevenDevils(Klondike):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 7 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7] open card.
      Build down in rank by alt color from any but _reserve_. Play top.

    _reserve_
      Pile 7 over 2 col E. Init deal 1 card. Build none. Play top.

    _talon_
      Pile 1 NW. Deal 1 card on _reserve_.

    _waste_
      Pile 1 E _talon_. Build none. Play top on _foundation_.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play none.

    seealso::
      <http://en.wikipedia.org/wiki/Seven_Devils>
    ------
    :cvar Layout _layout_: layout.JaneLayout
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: SevenDevils_RowStack (max_move=1)
    :cvar Stack _reserve_: stack.OpenStack
    :cvar Hint _hint_ = CautiousDefaultHint
    """
    __info__ = dict(id=434, name='Seven Devils', game_type=GT.RAGLAN, decks=2,
                    skill_level=SL.MOSTLY_LUCK, version='0.91fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = stack.WasteTalon
    _row_ = Wrap(SevenDevils_RowStack, max_move=1)
    _layout_ = layout.JaneLayout
    _reserves_ = stack.OpenStack

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.
        Add talon to dropstacks.

        .. \_create_game(rows=7, reserves=7, playcards=16, texts=False)
             -> Layout
        """
        kwdefault(kw, rows=7, reserves=7, playcards=16, texts=False)
        l, s = super(Sevendevils, self)._create_game(**kw), self.s

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]:  [1, 2, 3, 4, 5, 6, 7] top open.
          - s[reserves]: 1 ea open.

        .. \_start([flip=False, reverse=True]) -> None
        """
        super(SevenDevils, self)._start(**kw)
        self.s['talon'].dealRow(rows=self.s['reserves'])


class Senate(SevenDevils):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 4 horz NW. Init deal 1 card. Build down in rank by same suit. Play
      top.

    _reserve_
      Pile 8 over 2 col N. Init deal 1 card. Build none. Play top.

    _talon_
      Pile 1 NE. Deal 1 card on _reserve_.

    _foundation_
      Pile 8 over 2 col E. Init deal base ACE. Build up in rank by same
      suit. Play top.
    ------
    :cvar Layout _layout_: layout.SenateLayout
    :cvar Stack _talon_: stack.DealReserveTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack
    :cvar Stack _reserve_: stack.OpenStack
    :cvar Hint _hint_ = CautiousDefaultHint
    """
    __info__ = dict(id=388, name='Senate', game_type=GT.RAGLAN, decks=2,
                    skill_level=SL.BALANCED, version='0.90fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _layout_ = layout.SenateLayout
    _talon_ = stack.DealReserveTalon
    _row_ = stack.SS_RowStack


    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=4, reserves=8, ncols=4, playcards=10) -> Layout
        """
        kwdefault(kw, rows=4, reserves=8, ncols=4, playcards=10)
        return super(Senate, self)._create_game(**kw)

    def _pack_place(self, cards):
        """
        _pack_place(cards:seq(Card ...)) -> seq(Card ...)

        Overide to return ACE on top by rank, suit, deck for _foundation_ deal.
        """
        return place.MoveToTop(cards, place.AllAces)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[foundations]: all ACE.
          - s[reserves]: 1 ea open.
          - s[rows]:  1 ea open.

        .. \_start([]) -> None
        """
        self.s['talon'].dealRow(rows=self.s['foundations'], frames=0)
        self.s['talon'].dealRow(rows=self.s['reserves'])
        self.s['talon'].dealRow()



class SenatePlus(Senate):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 5 horz NW. Init deal 1 card. Build down in rank by same suit. Play
      top.

    _reserve_
      Pile 8 over 2 col N. Init deal 1 card. Build none. Play top.

    _talon_
      Pile 1 NE. Deal 1 card on _reserve_.

    _foundation_
      Pile 8 over 2 row E _row_. Init deal base ACE. Build up in rank by same
      suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.DealReserveTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack
    :cvar Stack _reserve_: stack.OpenStack
    :cvar Hint _hint_ = CautiousDefaultHint
    """
    __info__ = dict(id=389, name='Senate +', game_type=GT.RAGLAN, decks=2,
                    skill_level=SL.BALANCED, version='0.90fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=5, reserves=8, ncols=4, playcards=10) -> Layout
        """
        kw.setdefault('rows', 5)
        return super(SenatePlus, self)._create_game(**kw)


class Phoenix(Klondike):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 6 horz S _foundation_. Init deal 6 open card. Build
      down in rank by alt color. Play seq.

    _reserve_
      Pile 16 over 2 col W E. Init deal 1 card. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.PhoenixLayout
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Stack _reserve_: stack.OpenStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=263, name='Phoenix', game_type=(GT.RAGLAN | GT.OPEN),
                    decks=1, skill_level=SL.MOSTLY_SKILL,
                    version='0.80fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _layout_ = layout.PhoenixLayout
    _talon_ = stack.InitialDealTalon
    _row_ = stack.AC_RowStack
    _reserve_ = stack.OpenStack
    _hint_ = CautiousDefaultHint

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=6, reserves=16) -> Layout
        """
        kwdefault(kw, rows=6, reserves=16)
        return super(Phoenix, self)._create_game(**kw)

    def _start(self, flip=True, rows=6, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: 6 ea open.
          - s[reserves]: 1 ea open.

        .. \_start([flip=True, rows=6]) -> None
        """
        for i in range(rows - 1):
            self.s['talon'].dealRow(flip=flip, frames=0)
        self.s['talon'].dealRow()
        self.s['talon'].dealRow(rows=self.s['reserves'])


class Arizona(Phoenix):
    """
    Finish cards on _foundation_ within 1 turn.

    _layout_
      .. layout.KlondikeLayout
    _row_
      .. stack.RK_RowStack
      Pile 6 horz S _foundation_. Init deal 6 open card.
      Build down in rank alone. Play seq.
    _reserve_
      .. stack.OpenStack
      Pile 16 over 2 col W E. Init deal 1 card.
      Build none. Play top.
    _foundation_
      .. stack.SS_Foundation
      Pile 4 horz N.
      Build up in rank by same suit. Play top.
     _talon_
       .. stack.InitialDealTalon
    _hint_
      .. hint.CautiousDefaultHint
    """
    __info__ = dict(id=390, name='Arizona', game_type=(GT.RAGLAN | GT.OPEN),
                    decks=1, skill_level=SL.MOSTLY_SKILL,
                    version='0.90fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = stack.RK_RowStack


class Lanes(Klondike):
    """
    Finish cards on _foundation_ within 2 turn.

    _row_
      Pile 6 horz S _foundation_. Init deal 3 open card. Build down in rank by
      alt color. Play top.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Init deal base ACE. Build up in rank by same suit. Play
      none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=2)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation (max_move=0)
    :cvar Stack _row_: stack.AC_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=326, name='Lanes', game_type=GT.KLONDIKE, decks=1,
                    redeals=1, skill_level=SL.BALANCED, version='0.90fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, max_rounds=2)
    _foundation_ = Wrap(stack.SS_Foundation, max_move=0)
    _row_ = Wrap(stack.AC_RowStack, max_move=1)
    _hint_ = CautiousDefaultHint

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=6, round_text='ne') -> Layout
        """
        kwdefault(kw, rows=6, round_text='ne')
        return super(Lanes, self)._create_game(**kw)

    def _pack_place(self, cards):
        """
        _pack_place(cards:seq(Card ...)) -> seq(Card ...)

        Overide to return ACE on top by rank, suit, deck for _foundation_ deal.
        """
        return place.MoveToTop(cards, place.AllAces)

    def _start(self, flip=True, rows=2, **kw):
        """
        Deal initial cards for new game.
          - s[foundations]: all ACE.
          - s[rows]:  2 ea open.

        .. \_start([flip=True, rows=2]) -> None
        """
        self.s['talon'].dealRow(rows=self.s['foundations'], frames=0)
        for i in range(rows - 1):
            self.s['talon'].dealRow(flip=flip, frames=0)
        self.s['talon'].dealRow()


class ThirtySix(Klondike):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 6 horz S _foundation_. Init deal 6 open card while auto-finish.
      Build down in rank alone. Play seq.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation (max_move=0)
    :cvar Stack _row_: stack.RK_RowStack
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=327, name='Thirty Six', game_type=GT.KLONDIKE, decks=1,
                    skill_level=SL.BALANCED, version='0.90fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = stack.WasteTalon
    _foundation_ = Wrap(stack.SS_Foundation, max_move=0)
    _row_ = stack.RK_RowStack

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=6) -> Layout
        """
        kw.setdefault('rows', 6)
        return super(ThirtySix, self)._create_game(**kw)

    def _start(self, rows=6, **kw):
        """
        Deal initial cards for new game.
          - s[rows]:  6 ea open. drop w/ no replace.

        .. \_start([rows=6]) -> None
        """
        for i in range(rows - 1):
            self.s['talon'].deal_row_or_drop(frames=0, ncards=cs.MAX)
        self.s['talon'].deal_row_or_drop(ncards=cs.MAX)


class Q_C_(Klondike):
    """
    Finish cards on _foundation_ within 2 turn.

    _row_
      Pile 6 horz S _foundation_. Init deal 4 open card. Build down in rank by
      same suit. Play top.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_ or auto-finish.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play none.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=2)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation (max_move=0)
    :cvar Stack _row_: stack.SS_RowStack (max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=350, name='Q.C.', game_type=GT.KLONDIKE, decks=2,
                    redeals=1, skill_level=SL.BALANCED, version='0.90fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = Wrap(Q_C__Talon, max_rounds=2)
    _waste_ = Q_C__WasteStack
    _foundation_ = Wrap(stack.SS_Foundation, max_move=0)
    _row_ = Wrap(stack.SS_RowStack, max_move=1)
    _hint_ = CautiousDefaultHint

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=6, round_text='ss') -> Layout
        """
        kwdefault(kw, rows=6, round_text='ss')
        return super(Q_C_, self)._create_game(**kw)

    def _start(self, flip=True, rows=4, **kw):
        """
        Deal initial cards for new game.
          - s[rows]:  4 ea open.

        .. \_start([flip=True, rows=4]) -> None
        """
        for i in range(rows - 1):
            self.s['talon'].dealRow(flip=flip, frames=0)
        self.s['talon'].dealRow()

    @state.move_state('fill')
    def _auto_fill(self, stack=None):
        """
        Fill stack if _row_ when gap from _waste_.

        *Parameter*:
          stack : Stack
            pile just played
        """
        fill.fromWaste(self, stack, self.game.s['rows'])


class AuntMary(Klondike):
    """
    Finish cards on _foundation_ within 1 turn.
    _layout_
      .. layout.KlondikeLayout
    _row_
      .. stack.AC_RowStack (base_rank=KING)
      Pile 6 horz S _foundation_. Init deal 6 top [6..1] open card.
      Build down in rank by alt color. Play seq. Base KING.
    _talon_
      .. stack.WasteTalon
      Pile 1 NW.
      Deal 1 card on _waste_.
    _waste_
      .. stack.WasteStack
      Pile 1 E _talon_.
      Build none. Play top.
    _foundation_
      .. stack.SS_Foundation
      Pile 4 horz N.
      Build up in rank by same suit. Play top.
    _hint_
      .. hint.DefaultHint
    """
    __info__ = dict(id=407, name='Aunt Mary', game_type=GT.KLONDIKE, decks=1,
                    skill_level=SL.BALANCED, version='0.90fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = stack.WasteTalon

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=6) -> Layout
        """
        kw.setdefault('rows', 6)
        return super(AuntMary, self)._create_game(**kw)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: 6 ea top [6..1] open.

        .. \_start([]) -> None
        """
        for i in range(1, len(self.s['rows'])):
            self.s['talon'].dealRow(rows=self.s['rows'][:i], frames=0)
            self.s['talon'].dealRow(rows=self.s['rows'][i:], frames=0,
                                    flip=False)
        self.s['talon'].dealRow()


class DoubleDot(Klondike):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 8 horz S _foundation_. Init deal 1 card. Build
      down in rank alone by 2 wrap. Play seq.

    _talon_
      Pile 1 NW. Deal 1 card on _row_.

    _foundation_
      Pile 4 horz N. Init deal base ACE clubs spades TWO hearts diamonds.
      Build up in rank by same suit by 2. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation (dir=2, mod=13)
    :cvar Stack _row_: stack.RK_RowStack (dir=-2, mod=13)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=420, name='Double Dot', game_type=GT.KLONDIKE, decks=1,
                    skill_level=SL.BALANCED, version='0.90fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = stack.DealRowTalon
    _waste_ = None
    _row_ = Wrap(stack.RK_RowStack, dir=-2, mod=13)
    _foundation_ = Wrap(stack.SS_Foundation, dir=2, mod=13)

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=8) -> Layout
        """
        kw.setdefault('rows', 8)
        return super(DoubleDot, self)._create_game(**kw)

    def _pack_place(self, cards):
        """
        _pack_place(cards:seq(Card ...)) -> seq(Card ...)

        Overide to return ACE and Two on top by rank, suit, deck for
        _foundation_ deal.
        """
        return place.MoveToTop(cards, place.AcesTwos)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[foundations]: set ACE set TWO.
          - s[rows]: 1 ea open.

        .. \_start([]) -> None
        """
        self.s['talon'].dealRow(rows=self.s['foundations'], frames=0)
        self.s['talon'].dealRow()


class MovingLeft(Klondike):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 10 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7, 8 ,9, 10]
      card. Build down in rank by alt color. Play seq. Gap move piles W. Base
      KING.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=470, name='Moving Left', game_type=GT.KLONDIKE,
                    decks=2, skill_level=SL.MOSTLY_SKILL,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = stack.WasteTalon

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=10, playcards=24) -> Layout
        """
        kwdefault(kw, rows=10, playcards=24)
        super(MovingLeft, self)._create_game(**kw)

    @state.move_state('fill')
    def _auto_fill(self, stack):
        """
        Fill stack if _row_ when gap moving right seq on pile.

        *Parameter*:
          stack : Stack
            pile just played
        """
        rows = self.s['rows']
        if not stack.cards and stack in rows:
            index = list(rows).index(stack)
            if index < len(rows) - 1:
                from_stack = rows[index + 1]
                pile = from_stack.SEQEUNCE
                if pile:
                    self.move(len(pile), from_stack, stack)


class Souter(MovingLeft):
    """
    Finish cards on _foundation_ within 2 turn.

    _row_
      Pile 10 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7, 8 ,9, 10]
      card. Build down in rank by alt color. Play seq. Gap move piles W. Base
      KING.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=2)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=471, name='Souter', game_type=GT.KLONDIKE, decks=2,
                    redeals=1, skill_level=SL.BALANCED, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, max_rounds=2)

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(round_text='ne') -> Layout
        """
        kw.setdefault('round_text', 'ne')
        return super(Souter, self)._create_game(**kw)


class Cassim(Klondike):
    """
    Finish cards on _foundation_ without limit turn.

    _row_
      Pile 7 horz S _foundation_. Init deal 4 open card. Build
      down in rank by alt color. Play seq. Base KING.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=INFINITE)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=475, name='Cassim', game_type=GT.KLONDIKE, decks=1,
                    redeals=cs.INFINITE, skill_level=SL.BALANCED,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _start(self, flip=True, rows=4, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: 4 ea open.

        .. \_start([flip=True, rows=4]) -> None
        """
        for i in range(rows - 1):
            self.s['talon'].dealRow(flip=flip, frames=0)
        self.s['talon'].dealRow()


class BigForty(Cassim):
    """
    Finish cards on _foundation_ without limit turn.

    _row_
      Pile 10 horz S _foundation_. Init deal 4 open card. Build
      down in rank by same suit. Play seq.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=INFINITE)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.SS_RowStack
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=473, name='Big Forty', game_type=GT.KLONDIKE,
                    decks=1, redeals=cs.INFINITE, skill_level=SL.BALANCED,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = stack.SS_RowStack

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=10) -> Layout
        """
        kw.setdefault('rows', 10)
        return super(BigForty, self)._create_game(**kw)


class AliBaba(BigForty):
    """
    Finish cards on _foundation_ without limit turn.

    _layout_
      .. layout.KlondikeLayout
    _row_
      .. stack.SS_RowStack
      Pile 10 horz S _foundation_. Init deal 4 open card.
      Build down in rank by same suit. Play seq.
    _talon_
      .. stack.WasteTalon (max_rounds=INFINITE)
      Pile 1 NW.
      Deal 1 card on _waste_.
    _waste_
      .. stack.WasteStack
      Pile 1 E _talon_.
      Build none. Play top.
    _foundation_
      .. stack.SS_Foundation
      Pile 4 horz N. Init deal base ACE.
      Build up in rank by same suit. Play top.
    _hint_
      .. hint.DefaultHint
    """
    __info__ = dict(id=474, name='Ali Baba', game_type=GT.KLONDIKE, decks=1,
                    redeals=cs.INFINITE, skill_level=SL.BALANCED,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _pack_place(self, cards):
        """
        _pack_place(cards:seq(Card ...)) -> seq(Card ...)

        Overide to return ACE on top by rank, suit, deck for _foundation_ deal.

        :Parameters:
          cards : tuple(Cards..)
            cards to sort places.

        :return: tuple of newly sorted cards for specific deal placement.
        """
        return place.MoveToTop(cards, place.AllAces)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[foundations]: all ACE.
          - s[rows]: 4 ea open.

        .. \_start([flip=True, rows=4]) -> None
        """
        self.s['talon'].dealRow(rows=self.s['foundations'], frames=0)
        super(AliBaba, self)._start(**kw)


class Saratoga(Klondike):
    """
    Finish cards on _foundation_ without limit turn.

    _row_
      Pile 7 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7] open card.
      Build down in rank by alt color. Play seq. Base KING.

    _talon_
      Pile 1 NW. Deal 3 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=INFINITE,
      num_deal=3)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=479, name='Saratoga', game_type=GT.KLONDIKE,
                    decks=1, redeals=cs.INFINITE, skill_level=SL.BALANCED,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, max_rounds=cs.INFINITE, num_deal=3)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: [1, 2, 3, 4, 5, 6, 7] open.

        .. \_start([flip=True, reverse=True]) -> None
        """
        kw.setdefault('flip', True)
        super(Saratoga, self)._start(**kw)


class Whitehorse(Saratoga):
    """
    Finish cards on _foundation_ without limit turn.

    _row_
      Pile 7 horz S _foundation_. Init deal 1 open card. Build down in rank by
      alt color. Play seq. Gap deal 1 card from _talon_. Base KING.

    _talon_
      Pile 1 NW. Deal 3 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=INFINITE,
      num_deal=3)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=491, name='Whitehorse', game_type=GT.KLONDIKE,
                    decks=1, redeals=cs.INFINITE, skill_level=SL.BALANCED,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: 1 ea open.

        .. \_start([]) -> None
        """
        self.s['talon'].dealRow()

    @state.move_state('fill')
    def _auto_fill(self, stack):
        """
        Fill stack if _row_ when gap from _waste_.

        *Parameters*:
          stack : Stack
            pile just played
        """
        fill.fromWaste(self, stack, self.s['rows'])


class Boost(Klondike):
    """
    Finish cards on _foundation_ within 3 turn.

    _row_
      Pile 4 horz S _foundation_. Init deal [1, 2, 3, 4] card. Build down in
      rank by alt color. Play top. Base KING.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=3)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=518, name='Boost', game_type=(GT.KLONDIKE |
                    GT.ORIGINAL), decks=1, redeals=2, skill_level=SL.BALANCED,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, max_rounds=3)

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=4, round_text='ne') -> Layout
        """
        kwdefault(kw, rows=4, round_text='ne')
        return super(Boost, self)._create_game(**kw)


class GoldRush(Klondike):
    """
    Finish cards on _foundation_ within 3 turn.

    _row_
      Pile 7 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7] card. Build
      down in rank by alt color. Play top. Base KING.

    _talon_
      Pile 1 NW. Deal 3 card on _waste_. Each turn deal -1 card.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: canfield.CanfieldRush_Talon (max_rounds=3)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=532, name='Gold Rush', game_type=GT.KLONDIKE, decks=1,
                    redeals=2, skill_level=SL.BALANCED, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = Wrap(canfield.CanfieldRush_Talon, max_rounds=3)

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(round_text='ne') -> Layout
        """
        kw.setdefault('round_text', 'ne')
        return super(GoldRush, self)._create_game(**kw)


class GoldMine(Klondike):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 7 horz S _foundation_. Build down in rank by alt color. Play top.

    _talon_
      Pile 1 NW. Deal 3 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon (num_deal=3)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: GoldMine_RowStack
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=572, name='Gold Mine', game_type=GT.NUMERICA, decks=1,
                    skill_level=SL.MOSTLY_SKILL, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, num_deal=3)
    _row_ = GoldMine_RowStack

    def _start(self, **kw):
        """
        Deal initial cards for new game.

        .. \_start([]) -> None
        """
        pass


class LuckyThirteen(game.Game):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 13 over 3 row S _foundation_. Init deal 4 card. Build down in rank
      alone. Play top. Base none.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.RK_RowStack (base_rank=GAP, max_move=1)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=585, name='Lucky Thirteen', game_type=GT.ONE_DECK,
                    decks=1, skill_level=SL.MOSTLY_LUCK,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _layout_ = layout.HarpAltLayout
    _talon_ = stack.InitialDealTalon
    _foundation_ = stack.SS_Foundation
    _row_ = Wrap(stack.RK_RowStack, base_rank=cs.GAP, max_move=1)
    _hint_ = CautiousDefaultHint

    def _create_game(self, playcards=0):
        """
        Create game format.

        Overide pile placements based on current group attributes.

        .. \_create_game(playcards=0) -> Layout
        """
        l, s = layout.Layout(self), self.s
        offset = (l.XOFFSET, 0) if playcards > 0 else (0, 0)
        dx = l._get_stack_width(self, playcards, width=l.XS)
        self.table_size = (l.XM + 5 * dx, l.YM + 4 * l.YS,)
        for y, row in zip(l.col_iter(y=l.YM + l.YS, npiles=3), (5, 3, 5,)):
            for x in l.row_iter(x=l.XM + (5 - row) / 2 * dx, npiles=row, dx=dx):
                s['rows'].append(self._row_(x, y, game=self, offset=offset))
        dx = (self.width - l.NSUITS * l.XS) / 2
        for x, suit in zip(l.row_iter(x=dx, npiles=l.NSUITS), l.SUITS):
            s['foundations'].append(self._foundation_(x, l.YM, game=self,
                                 suit=suit))
        s['talon'] = self._talon_(l.XM, self.height - l.YS, game=self)
        l.defaultStackGroups()
        return l

    def _start(self, flip=True, rows=4, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: 4 ea open.

        .. \_start([flip=True, rows=4]) -> None
        """
        for i in range(rows - 1):
            self.s['talon'].dealRow(flip=flip, frames=0)
        self.s['talon'].dealRow()


class LuckyPiles(LuckyThirteen):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 13 over 3 row S _foundation_. Init deal 4 card. Build either in
      rank by same suit. Play top. Base KING.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.InitialDealTalon
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.UD_SS_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.CautiousDefaultHint
    """
    __info__ = dict(id=586, name='Lucky Piles', game_type=GT.FAN_TYPE,
                    decks=1, skill_level=SL.MOSTLY_SKILL,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _row_ = Wrap(stack.UD_SS_RowStack, base_rank=cs.KING)

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(playcards=7) -> Layout
        """
        kw.setdefault('playcards', 7)
        return super(LuckyPiles, self)._create_game(**kw)


class Legion(Klondike):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 8 horz S _foundation_. Init deal [1, 2, 4, 6, 6, 4, 2, 1] alt open
      card. Build down in rank by alt color. Play seq. Base KING.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack (base_rank=KING)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=607, name='Legion', game_type=GT.KLONDIKE, decks=1,
                    skill_level=SL.BALANCED, version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = stack.WasteTalon

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=8) -> Layout
        """
        kw.setdefault('rows', 8)
        return super(Legion, self)._create_game(**kw)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: [1, 3, 5, 7, 7, 5, 3, 1] alt open.

        .. \_start([]) -> None
        """
        self.s['talon'].dealRow()
        for i in range(3):
            self.s['talon'].dealRow(rows=self.s['rows'][i:-i], flip=False)
            self.s['talon'].dealRow(rows=self.s['rows'][i:-i], flip=True)


class BigBertha(game.Game):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 15 horz S _foundation_. Init deal 6 card. Build down in rank by alt
      color. Play seq.

    _reserve_
      Pile 14 horz S. Init deal 1 card. Build none. Play top.

    _foundation_
      Pile 8 horz N, 1 SE. N build up in rank by same suit to QUEEN. SE build
      in same rank from base KING. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation (max_cards=12),
      stack.RK_Foundation (base_rank=KING, dir=0, max_cards=8)
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Stack _reserve_: stack.OpenStack
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=630, name='Big Bertha', game_type=(GT.RAGLAN |
                    GT.OPEN), decks=2, skill_level=SL.MOSTLY_SKILL,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _layout_ = layout.KlondikeLayout
    _talon_ = stack.InitialDealTalon
    _foundations_ = (Wrap(stack.SS_Foundation, max_cards=12),
                     Wrap(stack.RK_Foundation, base_rank=cs.KING,
                     dir=0, max_cards=8),)
    _row_ = stack.AC_RowStack
    _reserve_ = stack.OpenStack

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=15, reserves=14, playcards=15) -> Layout
        """
        kwdefault(kw, rows=15, reserves=14, playcards=15)
        return super(BigBertha, self)._create_game(**kw)

    def _start(self, flip=True, rows=6, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: 6 ea open.
          - s[reserves]: 1 ea open

        .. \_start([]) -> None
        """
        for i in range(rows - 1):
            self.s['talon'].dealRow(flip=flip, frames=0)
        self.s['talon'].dealRow()
        self.s['talon'].dealRow(rows=self.s['reserves'])


class Athena(Klondike):
    """
    Finish cards on _foundation_ without limit turn.

    _layout_
      .. layout.KlondikeLayout
    _row_
      .. stack.AC_RowStack (base_rank=KING)
      Pile 7 horz S _foundation_. Init deal 4 alt open card.
      Build down in rank by alt color. Play seq. Base KING.
    _talon_
      .. stack.WasteTalon (max_rounds=INFINITE)
      Pile 1 NW.
      Deal 1 card on _waste_.
    _waste_
      .. stack.WasteStack
      Pile 1 E _talon_.
      Build none. Play top.
    _foundation_
      .. stack.SS_Foundation
      Pile 4 horz N.
      Build up in rank by same suit. Play top.
    _hint_
      .. hint.DefaultHint
    """
    __info__ = dict(id=633, name='Athena', game_type=GT.KLONDIKE, decks=1,
                    redeals=cs.INFINITE, skill_level=SL.BALANCED,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    def _start(self, flips=(False, True) * 2, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: 4 ea alt open.

        .. \_start([flips=(False, True) * 2]) -> None
        """
        for flip in flips[:-1]:
            self.s['talon'].dealRow(frames=frames, flip=flip)
        self.s['talon'].dealRow(flip=flips[-1])


class Kingsley(Klondike):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 7 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7] card. Build
      up in rank by alt color. Play seq. Base ACE.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 4 horz N. Build down in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation (base_rank=KING,
      dir=-1)
    :cvar Stack _row_: stack.AC_RowStack (base_rank=ACE, dir=1)
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=667, name='Kingsley', game_type=GT.KLONDIKE, decks=1,
                    skill_level=SL.MOSTLY_LUCK, version='0.94fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = stack.WasteTalon
    _foundation_ = Wrap(stack.SS_Foundation, base_rank=cs.KING,
                                dir=-1)
    _row_ = Wrap(stack.AC_RowStack, base_rank=cs.ACE, dir=1)


class Scarp(Klondike):
    """
    Finish cards on _foundation_ within 1 turn.

    _row_
      Pile 13 horz S _foundation_. Init deal [1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
      11, 12, 13] open card. Build down in rank by alt color. Play seq.

    _talon_
      Pile 1 NW. Deal 1 card on _row_.

    _foundation_
      Pile 4 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.DealRowTalon
    :cvar Stack _waste_: None
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: stack.AC_RowStack
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=669, name='Scarp', game_type=(GT.GYPSY | GT.ORIGINAL),
                    decks=3, skill_level=SL.MOSTLY_SKILL,
                    version='0.94fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = stack.DealRowTalon
    _waste_ = None
    _row_ = stack.AC_RowStack

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=13, playcards=28) -> Layout
        """
        kwdefault(kw, rows=13, playcards=28)
        return super(Scarp, self)._create_game(**kw)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: [1..13] open.

        .. \_start([flip=True, reverse=True]) -> None
        """
        kw.setdefault('flip', True)
        super(Scarp, self)._start(**kw)


class EightSages(Klondike):
    """
    Finish cards on _foundation_ within 2 turn.

    _row_
      Pile 8 horz S _foundation_. Init deal 1 card. Build
      down in rank by alt color from _waste_. Play seq.

    _talon_
      Pile 1 NW. Deal 1 card on _waste_.

    _waste_
      Pile 1 E _talon_. Build none. Play top.

    _foundation_
      Pile 8 horz N. Build up in rank by same suit. Play top.
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_: stack.WasteTalon (max_rounds=2)
    :cvar Stack _waste_: stack.WasteStack
    :cvar Stack _foundation_: stack.SS_Foundation
    :cvar Stack _row_: EightSages_Row
    :cvar Hint _hint_: hint.DefaultHint
    """
    __info__ = dict(id=726, name='Eight Sages', game_type=GT.KLONDIKE,
                    decks=2, redeals=1, skill_level=SL.MOSTLY_LUCK,
                    version='1.10fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _talon_ = Wrap(stack.WasteTalon, max_rounds=2)
    _row_ = EightSages_Row

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=8, playcards=12, round_text='ne') -> Layout
        """
        kwdefault(kw, rows=8, playcards=12, round_text='ne')
        return super(EightSages, self)._create_game(**kw)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: 1 ea open.

        .. \_start([]) -> None
        """
        self.s['talon'].dealRow()

class Glacier(game.Game):
    """
    Finish cards on _foundation_ within a turn.

    _row_
      Pile 12 horz S _foundation_. Init deal 1 card. Build down in rank alone.
      Play seq.

    _talon_
      Pile 1 NW. Build None. Deal 2 card on _waste_.

    _waste_
      Pile 1 E _talon_. Init deal 1 card. Build None. Play top.

    _Foundation_
      Pile 4 horz N. Build up in rank by same suit wrap. Play top. Max 26 card
    ------
    :cvar Layout _layout_: layout.KlondikeLayout
    :cvar Stack _talon_:  stack.WasteTalon  (num_deal=2)
    :cvar Stack _waste_:  stack.WasteStack (max_cards=2)
    :cvar Stack _foundation_: stack.SS_Foundation (mod=13, max_cards=26)
    :cvar Stack _row_: stack.RK_RowStack (mod=13)
    :cvar Hint _hint_: hint.deafultHint
    """
    __info__ = dict(id=687, name='Glacier', game_type=GT.TWO_DECK,
                    decks=2, skill_level=SL.BALANCED,
                    version='0.93fc')
    __author__ = 'Skomoroh'
    __version__ = 7.70

    _layout_ = layout.KlondikeLayout
    _talon_ = Wrap(stack.WasteTalon, num_deal=2)
    _waste_ = Wrap(stack.WasteStack, max_cards=2)
    _foundation_ = Wrap(stack.SS_Foundation, mod=13,
                                max_cards=26)
    _row_ = Wrap(stack.RK_RowStack, mod=13)

    def _create_game(self, **kw):
        """
        Create game format.

        Augment pile placements based on current form and group attributes.

        .. \_create_game(rows=12, playcards=20, wastecards=2, bases=SUIT)
             -> Layout
        """
        kwdefault(kw, rows=12, playcards=20, wastecards=2, bases=range(4))
        return super(Glacier, self)._create_game(**kw)

    def _start(self, **kw):
        """
        Deal initial cards for new game.
          - s[rows]: 1 ea open.

        .. \_start([]) -> None
        """
        self.s['talon'].dealRow()


PROVIDES = [Klondike, CasinoKlondike, VegasKlondike, KlondikeByThrees,
            ThumbAndPouch, Whitehead, SmallHarp, Eastcliff, Easthaven,
            Westcliff, Westhaven, PasSeul, BlindAlleys, Somerset, Canister,
            AgnesSorel, EightTimesEight, AchtmalAcht, Batsford, Stonewall,
            FlowerGarden, KingAlbert, Raglan, Brigade, Jane, AgnesBernauer,
            Phoenix, Jumbo, OpenJumbo, Lanes, ThirtySix, Q_C_,
            NorthwestTerritory, Morehead, Senate, SenatePlus, Arizona,
            AuntMary, DoubleDot, SevenDevils, DoubleEasthaven,
            TripleEasthaven, MovingLeft, Souter, BigForty, AliBaba, Cassim,
            Saratoga, Whitehorse, Boost, ArticGarden, GoldRush, Usk,
            BatsfordAgain, GoldMine, LuckyThirteen, LuckyPiles,
            AmericanCanister, BritishCanister, Legion, QueenVictoria,
            BigBertha, Athena, Chinaman, EightByEight, Kingsley, Scarp,
            EightSages, Glacier]